package com.zhixiang.xaec.entity.system;


import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.apache.commons.lang.StringUtils;
import org.hibernate.cfg.Comment;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.GrantedAuthorityImpl;
import org.springframework.security.userdetails.UserDetails;

import com.zhixiang.core.menu.TopModule;
import com.zhixiang.core.util.AppUtil;


@Entity
@Table(name = "sys_app_user")
@Comment("系统用户")
@SuppressWarnings({"rawtypes","unchecked"})
public class AppUser implements UserDetails
{

    private static final long serialVersionUID = -2241262369664751220L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Comment("ID")
    private Long userId;

    @Comment("账号")
    private String username;

    @Comment("密码")
    private String password;

    @ManyToOne(cascade = CascadeType.ALL, optional = false)
    @JoinColumn(name = "a_s_id", referencedColumnName = "id")
    private Staff staff;

//    @ManyToMany
//    @JoinTable(name = "sys_user_role", joinColumns = {@JoinColumn(name = "userId")}, inverseJoinColumns = {@JoinColumn(name = "roleId")})
    @ManyToOne(cascade = CascadeType.ALL, optional = false)
    @JoinColumn(name="user_role_id", referencedColumnName="roleId")
    private AppRole appRole;

    @Transient
    private Map<String, TopModule> topModules = new LinkedHashMap<String, TopModule>();

    @Transient
    private Set<String> rights = new HashSet<String>();

    @Override
    public GrantedAuthority[] getAuthorities()
    {
//        GrantedAuthority[] arrayOfGrantedAuthority = (GrantedAuthority[])appRoles.toArray(new GrantedAuthority[appRoles.size() + 1]);
//        arrayOfGrantedAuthority[(arrayOfGrantedAuthority.length - 1)] = new GrantedAuthorityImpl(
//            "ROLE_PUBLIC");
//        return arrayOfGrantedAuthority;
    	/**
    	 * 一个账户对应一个角色
    	 */
    	GrantedAuthority[] arrayOfGrantedAuthority = new GrantedAuthority[2];
    	arrayOfGrantedAuthority[0] = appRole;
    	 arrayOfGrantedAuthority[(arrayOfGrantedAuthority.length - 1)] = new GrantedAuthorityImpl("ROLE_PUBLIC");
    	 return arrayOfGrantedAuthority;
    }

    @Override
    public String getPassword()
    {
        return password;
    }

    @Override
    public String getUsername()
    {
        return username;
    }

    @Override
    public boolean isAccountNonExpired()
    {
        return true;
    }

    @Override
    public boolean isAccountNonLocked()
    {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired()
    {
        return true;
    }

    @Override
    public boolean isEnabled()
    {
        return true;
    }

    public Long getUserId()
    {
        return userId;
    }

    public void setUserId(Long userId)
    {
        this.userId = userId;
    }

    public void setUsername(String username)
    {
        this.username = username;
    }

    public void setPassword(String password)
    {
        this.password = password;
    }

    public AppRole getAppRole() {
		return appRole;
	}

	public void setAppRole(AppRole appRole) {
		this.appRole = appRole;
	}

	public Map<String, TopModule> getTopModules()
    {
        return topModules;
    }

    public void setTopModules(Map<String, TopModule> topModules)
    {
        this.topModules = topModules;
    }

    public Set<String> getRights()
    {
        return rights;
    }

    public void setRights(Set<String> rights)
    {
        this.rights = rights;
    }

    public void initMenuRights()
    {
        getTopModules().putAll(AppUtil.getPublicTopModules());
        AppRole approle = getAppRole();
//        Set<AppRole> localSet = getAppRoles();
        // Iterator localIterator = localSet.iterator();
        // while (localIterator.hasNext()) {}
//        for (AppRole approle : localSet)
//        {
            // AppRole approle = (AppRole)localIterator.next();
            if (approle.getRoleId().equals(AppRole.SUPER_ROLEID))
            {
                getRights().clear();
                getTopModules().clear();
                getRights().add("__ALL");
                getTopModules().putAll(AppUtil.getAllTopModels());
//                break;
            }
            if (StringUtils.isNotEmpty(approle.getRights()))
            {
                String[] as = approle.getRights().split("[,]");
                for (int i = 0; i < as.length; i++ )
                {
                    String str = as[i];
                    if (str.startsWith("Mod_"))
                    {
                        if (!getTopModules().containsKey(str))
                            getTopModules().put(as[i],
                                (TopModule)AppUtil.getAllTopModels().get(str));
                    }
                    else if (!getRights().contains(str)) getRights().add(str);
                }
            }

//        }
        ArrayList arraylist = new ArrayList();
        arraylist.addAll(getTopModules().values());
        Collections.sort(arraylist, new Comparator()
        {
            public int compare(TopModule paramAnonymousTopModule1,
                               TopModule paramAnonymousTopModule2)
            {
                if (paramAnonymousTopModule1.getSn().intValue() > paramAnonymousTopModule2.getSn().intValue())
                    return 1;
                return 0;
            }

            public int compare(Object obj, Object obj1)
            {
                return compare((TopModule)obj, (TopModule)obj1);
            }
        });
        getTopModules().clear();
        Iterator iterator1 = arraylist.iterator();
        while (iterator1.hasNext())
        {
            TopModule localTopModule = (TopModule)iterator1.next();
            getTopModules().put(localTopModule.getId(), localTopModule);
        }
    }
    
    public Staff getStaff()
    {
        return staff;
    }

    public void setStaff(Staff staff)
    {
        this.staff = staff;
    }

}
